﻿using System;
using System.Collections.Generic;
using System.Text;

namespace SpeakerRecognition
{
    /// <summary>
    /// 
    /// </summary>
    public class WindowCreator
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="winType"></param>
        /// <param name="winSize"></param>
        /// <returns></returns>
        public static double[] createWindowByType(String winType, int winSize)
        {
            switch (winType)
            {
                case "Hamming":
                    return createHammingWindow(winSize);
                    break;
                case "Rectangular":
                    return createRectangularWindow(winSize);
                    break;
                case "Hanning":
                    return createHanningWindow(winSize);
                    break;
                case "Cosine":
                    return createCosineWindow(winSize);
                    break;
                case "Gauss":
                    return createGaussWindow(winSize);
                    break;
                case "Nuttall":
                    return createNuttallWindow(winSize);
                    break;
            }
            return null;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="winSize"></param>
        /// <returns></returns>
        private static double[] createHammingWindow(int size)
        {
            double[] result = new double[size];
            for (int i = 0; i < size; i++)
            {
                result[i] = 0.54 - 0.46 * Math.Cos(2 * Math.PI * i / (size - 1));
            }
            return result;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="winSize"></param>
        /// <returns></returns>
        private static double[] createRectangularWindow(int size)
        {
            double[] result = new double[size];
            for (int i = 0; i < size; i++)
            {
                 result[i] = 1;
            }
            return result;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="winSize"></param>
        /// <returns></returns>
        private static double[] createHanningWindow(int size)
        {
            double[] result = new double[size];
            for (int i = 0; i < size; i++)
            {
                result[i] = 0.5 * (1 - Math.Cos(2 * Math.PI * i / (size - 1)));
            }
            return result;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="winSize"></param>
        /// <returns></returns>
        private static double[] createCosineWindow(int size)
        {
            double[] result = new double[size];
            for (int i = 0; i < size; i++)
            {
                result[i] = Math.Sin(Math.PI * i / (size - 1));
            }
            return result;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="winSize"></param>
        /// <returns></returns>
        private static double[] createGaussWindow(int size)
        {
            double[] result = new double[size];
            for (int i = 0; i < size; i++)
            {
                result[i] = Math.Pow(Math.E ,-0.5 * Math.Pow(((i- (size -1)/2 ))/(0.4 *(size -1)/2 ),2) );
            }
            return result;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="winSize"></param>
        /// <returns></returns>
        private static double[] createNuttallWindow(int size)
        {
            double[] result = new double[size];
            for (int i = 0; i < size; i++)
            {
                result[i] = 0.355768 - 0.487396 * Math.Cos(2 * Math.PI * i / (size - 1)) + 0.144232 * Math.Cos(4 * Math.PI * i / (size - 1)) - 0.012604 * Math.Cos(6 * Math.PI * i / (size - 1));
            }
            return result;
        }
    }
}
